package stopwatch;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import javax.swing.Timer;

import utility.Constants;
import database.Database;

final class Stopwatch implements ActionListener{

	private boolean	sessionIsRunning = false;
	private boolean sessionIsPaused = false;
	private int activityId;
	private StopwatchPanel stopwatchPanel;
	private long startTime;
	private long elapsedTime;
	private final Timer timer = new Timer(Constants.MM_MILLIS,this);
	private long lastUpdate;

	Stopwatch(final StopwatchPanel stopwatchPanel){
		if (stopwatchPanel == null) throw new RuntimeException("Null stopwatchPanel passed.");
		this.stopwatchPanel = stopwatchPanel;
		timer.setInitialDelay(0);
	}

	void startOrPauseOrResume(int activityId, boolean lap){		
		this.activityId = activityId;

		if (sessionIsRunning) 
			if(sessionIsPaused) resume(lap);
			else pause();
		else start(lap);
	}

	private void start(boolean lap){
		assert(! sessionIsRunning && ! sessionIsPaused);
		sessionIsRunning = true;
		startTime = System.currentTimeMillis();
		elapsedTime = 0;
		timer.start();
	}

	private void pause(){
		assert( sessionIsRunning && ! sessionIsPaused);
		sessionIsPaused = true;
		timer.stop();
		if (elapsedTime > 4*Constants.MM_MILLIS) 
			Database.addRecordedSession(activityId, startTime);
	}

	private void resume(boolean lap){
		assert(sessionIsRunning);
		timer.start();
		sessionIsPaused = false;
		startTime = System.currentTimeMillis();
	}

	boolean isSessionPaused(){
		return sessionIsPaused;
	}

	@Override
	public void actionPerformed(ActionEvent aa) {
		if (aa.getSource() == timer){
			if (sessionIsPaused) timer.stop();
			else{
				final GregorianCalendar a = new GregorianCalendar();
				a.setTimeInMillis(elapsedTime);
				a.setTimeZone(TimeZone.getTimeZone("GMT"));
				stopwatchPanel.updateDisplayedTime(a.get(Calendar.HOUR), a.get(Calendar.MINUTE));

				if (System.currentTimeMillis() - lastUpdate >= Constants.MM_MILLIS){
					lastUpdate = System.currentTimeMillis();
					elapsedTime += Constants.MM_MILLIS;
				}	
			}
		}
	}
}


